package com.sali.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.sali.entity.AlipayProperties;
import com.sali.qrcode.QRCodeUtil;
import com.sali.qrcode.QrCodeResponse;
import com.sali.qrcode.QrResponse;
import com.sali.vo.PayVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.ResourceUtils;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;


@Service
@EnableConfigurationProperties(AlipayProperties.class)
public class AlipayService {

    private static final Logger log = LoggerFactory.getLogger(AlipayService.class);


    @Autowired
    private AlipayProperties alipayProperties;

    /**
     * @return byte[]
     * @Description 阿里支付接口
     * @Date 1:05 2020/9/9
     * @Param [payVo]
     **/
    public byte[] alipay(PayVo payVo) {

        try {

            // 支付宝携带的参数在回调中可以通过request获取
            JSONObject json = new JSONObject();
            json.put("userId", payVo.getUserId());
            json.put("orderNumber", payVo.getOrderNumber());
            json.put("money", payVo.getMoney());
            json.put("ptype", payVo.getPtype());
            json.put("productId", payVo.getProductId());
            String params = json.toString();

            // 设置支付相关的信息
            AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
            // 自定义订单号
            model.setOutTradeNo(payVo.getOrderNumber());
            // 支付金额
            model.setTotalAmount(payVo.getMoney());
            // 支付的产品名称
            model.setSubject(payVo.getProductName());
            // 支付的请求体参数
            model.setBody(params);
            // 支付的超时时间
            model.setTimeoutExpress("30m");
            // 支付的库存id
            model.setStoreId(payVo.getStoreId());
            QrCodeResponse qrCodeResponse = qrcodePay(model);


            // 二维码合成
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            String logopath;
            try {
                logopath = ResourceUtils.getFile("classpath:favicon.png").getAbsolutePath();
            } catch (Exception ex) {
                logopath = new java.io.File("C:\\Users\\zh\\Desktop\\中台项目\\custom-springboot-starter\\sali-pay-controller-test\\src\\main\\resources\\favicon.png").getAbsolutePath();
            }
            BufferedImage buffImg = QRCodeUtil.encode(qrCodeResponse.getQr_code(), logopath, false);//获取二维码
            ImageOutputStream imageOut = ImageIO.createImageOutputStream(output);
            ImageIO.write(buffImg, "JPEG", imageOut);
            imageOut.close();
            ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray());

            return FileCopyUtils.copyToByteArray(input);
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    public boolean alipayCallback(HttpServletRequest request) throws UnsupportedEncodingException {
        // 1:获取支付宝GET过来反馈信息
        Map<String, String> params = new HashMap<>();
        Map requestParams = request.getParameterMap();
        for (Object o : requestParams.keySet()) {
            String name = (String) o;
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            params.put(name, new String(valueStr.getBytes("ISO-8859-1"), "UTF-8"));
        }

        //2：计算得出通知验证结果
        log.info("---->获取支付宝回传的参数---------------------------------->" + params);
        // 返回公共参数
        String tradeno = params.get("trade_no");
        ;
        //支付返回的请求参数body
        String bodyJson = params.get("body");
        log.info("---->:【支付宝】交易的参数信息是：{}，流水号是：{}", bodyJson, tradeno);
        try {
            JSONObject bodyJsonObject = JSONObject.parseObject(bodyJson);
            String userId = bodyJsonObject.getString("userId");
            String ptype = bodyJsonObject.getString("ptype");
            String orderNumber = bodyJsonObject.getString("orderNumber");
            log.info("---->:【支付宝】交易的参数信息是：userId:{}, ptype:{}，orderNumber是：{}", userId, ptype, orderNumber);


            // 课程支付成功，保存的订单交易明细
            log.info("---->:保存信息：tradeno:{}, bodyJson: {}", tradeno, bodyJson);

        } catch (Exception ex) {
            log.info("支付宝支付出现了异常.....");
            ex.printStackTrace();
            return false;
        }
        return true;
    }


    /**
     * 扫码运行代码
     * 验签通过返回QrResponse
     * 失败打印日志信息
     * 参考地址：https://opendocs.alipay.com/apis/api_1/alipay.trade.app.pay
     *
     * @param model
     * @return
     */
    public QrCodeResponse qrcodePay(AlipayTradePrecreateModel model) {
        // 1: 获取阿里请求客户端
        AlipayClient alipayClient = getAlipayClient();
        // 2: 获取阿里请求对象
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        // 3：设置请求参数的集合，最大长度不限
        request.setBizModel(model);
        // 设置异步回调地址
        request.setNotifyUrl(alipayProperties.getNotify_url());
        // 设置同步回调地址
        request.setReturnUrl(alipayProperties.getReturn_url());
        AlipayTradePrecreateResponse alipayTradePrecreateResponse = null;
        try {
            alipayTradePrecreateResponse = alipayClient.execute(request);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        QrResponse qrResponse = JSON.parseObject(alipayTradePrecreateResponse.getBody(), QrResponse.class);
        return qrResponse.getAlipay_trade_precreate_response();
    }

    /**
     * 获取AlipayClient对象
     *
     * @return
     */
    private AlipayClient getAlipayClient() {
        AlipayClient alipayClient =
                new DefaultAlipayClient(alipayProperties.getGatewayUrl(), alipayProperties.getApp_id(), alipayProperties.getMerchant_private_key(),
                        "JSON", alipayProperties.getCharset(), alipayProperties.getAlipay_public_key(), alipayProperties.getSign_type()); //获得初始化的AlipayClient
        return alipayClient;
    }
}